﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.Windows.Controls.Primitives;
using System.Runtime.InteropServices;
using M7;
using System.Threading;

namespace S7.Windows.Music
{
    /// <summary>
    /// Interaction logic for MediaPlayer.xaml
    /// </summary>
    public partial class MediaPlayer : Window
    {
        DispatcherTimer timer;



        #region Constructor
        public MediaPlayer()
        {
            InitializeComponent();
            IsPlaying(false);
            timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromMilliseconds(200);
            timer.Tick += new EventHandler(timer_Tick);
        }
        #endregion

        #region IsPlaying(bool)
        private void IsPlaying(bool bValue)
        {
            btnStop.IsEnabled = bValue;
            btnMoveBackward.IsEnabled = bValue;
            btnMoveForward.IsEnabled = bValue;
            btnPlay.IsEnabled = bValue;
            seekBar.IsEnabled = bValue;
            btnPrevious.IsEnabled = bValue;
            btnNext.IsEnabled = bValue;
        }
        #endregion

        #region Play and Pause
        private void btnPlay_Click(object sender, RoutedEventArgs e)
        {
            MediaEL.Play();
            if (Info.thrCalculateVotes.ThreadState == ThreadState.Aborted)
            {
                Info.thrCalculateVotes.Start();
            }
        }
        #endregion

        #region Stop
        private void btnStop_Click(object sender, RoutedEventArgs e)
        {
            MediaEL.Stop();
            btnPlay.Content = "Play";
            IsPlaying(false);
            btnPlay.IsEnabled = true;
        }
        #endregion

        #region Back and Forward
        private void btnMoveForward_Click(object sender, RoutedEventArgs e)
        {
            MediaEL.Position = MediaEL.Position + TimeSpan.FromSeconds(10);
        }

        private void btnMoveBackward_Click(object sender, RoutedEventArgs e)
        {
            MediaEL.Position = MediaEL.Position - TimeSpan.FromSeconds(10);
        }
        #endregion

        #region Seek Bar
        private void MediaEL_MediaOpened(object sender, RoutedEventArgs e)
        {
            if (MediaEL.NaturalDuration.HasTimeSpan)
            {
                TimeSpan ts = MediaEL.NaturalDuration.TimeSpan;
                seekBar.Maximum = ts.TotalSeconds;
                seekBar.SmallChange = 1;
                seekBar.LargeChange = Math.Min(10, ts.Seconds / 10);
            }

            Info.CurrentSong = lbSongs.SelectedItem as NSong;

            foreach (var item in Info.window.wrpLiveView.Children)
            {
                if ((item as TableControl).Connection != null)
                {
                    Msg SendMsg = new Msg();
                    SendMsg.enumMethod = enumMusic.Lyrics;
                    SendMsg.obj = (lbSongs.SelectedItem as NSong);
                    SendMsg.IP = (item as TableControl).Connection.current.IP;
                    SendMsg.port = (item as TableControl).Connection.current.Port;
                    Info.server.SendingQueue.Enqueue(SendMsg);
                }
            }
            timer.Start();
        }

        bool isDragging = false;

        void timer_Tick(object sender, EventArgs e)
        {
            if (!isDragging)
            {
                seekBar.Value = MediaEL.Position.TotalSeconds;
                currentposition = seekBar.Value;
            }
        }

        private void seekBar_DragStarted(object sender, DragStartedEventArgs e)
        {
            isDragging = true;
        }

        private void seekBar_DragCompleted(object sender, DragCompletedEventArgs e)
        {
            isDragging = false;
            MediaEL.Position = TimeSpan.FromSeconds(seekBar.Value);
        }
        #endregion

        #region FullScreen
        [DllImport("user32.dll")]
        static extern uint GetDoubleClickTime();

        System.Timers.Timer timeClick = new System.Timers.Timer((int)GetDoubleClickTime())
        {
            AutoReset = false
        };

        bool fullScreen = false;
        double currentposition = 0;

        private void MediaEL_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (!timeClick.Enabled)
            {
                timeClick.Enabled = true;
                return;
            }

            if (timeClick.Enabled)
            {
                if (!fullScreen)
                {
                    LayoutRoot.Children.Remove(MediaEL);
                    this.Background = new SolidColorBrush(Colors.Black);
                    this.Content = MediaEL;
                    this.WindowStyle = WindowStyle.None;
                    this.WindowState = WindowState.Maximized;
                    MediaEL.Position = TimeSpan.FromSeconds(currentposition);
                }
                else
                {
                    this.Content = LayoutRoot;
                    LayoutRoot.Children.Add(MediaEL);
                    this.Background = new SolidColorBrush(Colors.White);
                    this.WindowStyle = WindowStyle.SingleBorderWindow;
                    this.WindowState = WindowState.Normal;
                    MediaEL.Position = TimeSpan.FromSeconds(currentposition);
                }
                fullScreen = !fullScreen;
            }
        }
        #endregion

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            Info.thrCalculateVotes = new Thread(new ThreadStart(() =>
            {
                while (true)
                {
                    Genre.lstGenre = Genre.Search();
                    Song.lstSongs = Song.Search();
                    Artist.lstArtists = Artist.Search();
                    if (Info.MusicVotes == null)
                    {
                        Info.MusicVotes = new Dictionary<Genre, int>();
                        foreach (var genre in Genre.lstGenre)
                        {
                            Info.MusicVotes.Add(genre, 0);
                        }
                    }
                    var max = from item in Info.MusicVotes
                              where item.Value.Equals(Info.MusicVotes.Values.Max<int>())
                              select item.Key;

                    List<Genre> list = max.ToList();

                    int x = Info.rand.Next(0, list.Count);

                    var SelectedMusic = from song in Song.lstSongs
                                        from artist in Artist.lstArtists
                                        where song.GenreID.Equals(list[x].GenreID)
                                        && song.ArtistID.Equals(artist.ArtistID)
                                        select new { song.SongName, song.SongPath, artist.ArtistName, song.Lyrics };

                    Info.PlayingList = new List<NSong>();
                    foreach (var song in SelectedMusic)
                    {
                        Info.PlayingList.Add(new NSong(song.SongName, song.ArtistName, null, song.Lyrics, song.SongPath));
                    }
                    lbSongs.Dispatcher.Invoke(new ThreadStart(() =>
                        {
                            lbSongs.ItemsSource = Info.PlayingList;
                            lbSongs.SelectedIndex = 0;
                            MediaEL.Source = new Uri((lbSongs.SelectedItem as NSong).Path);
                        }));
                    Dictionary<Genre, int> newList = new Dictionary<Genre, int>();
                    foreach (var item in Info.MusicVotes)
                    {
                        newList.Add(item.Key, item.Value);
                    }
                    Info.MusicVotes = newList;
                    Thread.Sleep(1800000);
                }
            }));
            Info.thrCalculateVotes.IsBackground = true;

            Info.thrCalculateVotes.Start();
            IsPlaying(true);
        }

        private void lbSongs_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (lbSongs.SelectedItem != null)
            {
                MediaEL.Source = new Uri((lbSongs.SelectedItem as NSong).Path);
            }
            if (!btnPlay.Content.Equals("Play"))
            {
                btnPlay_Click(sender, new RoutedEventArgs());
            }
        }

        private void MediaEL_MediaEnded(object sender, RoutedEventArgs e)
        {
            if (lbSongs.SelectedIndex < lbSongs.Items.Count)
            {
                lbSongs.SelectedIndex = Info.rand.Next(0, lbSongs.Items.Count);
            }
            else
            {
                lbSongs.SelectedIndex = 0;
            }
            MediaEL.Source = new Uri((lbSongs.SelectedItem as NSong).Path);
            
        }
    }
}